package com.sky.aspect;

import com.sky.annotation.AutoFill;
import com.sky.context.BaseContext;
import com.sky.enumeration.OperationType;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.ObjectUtils;
import org.apache.ibatis.annotations.Insert;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.stereotype.Component;

import java.lang.reflect.Field;
import java.time.LocalDateTime;
import java.util.Arrays;

import static com.sky.enumeration.OperationType.INSERT;

/**
 * 自定义切面，实现公共字段自动填充处理逻辑
 */
@Aspect
@Component
@Slf4j
public class AutoFillAspect {
    /**
     * 切入点
     */
    @Pointcut("execution(* com.sky.mapper.*.*(..)) && @annotation(com.sky.annotation.AutoFill)")
    public void autoFillPointCut() {
    }

    /**
     * 前置通知，在通知中进行公共字段的赋值
     */
    @Before("autoFillPointCut()&&@annotation(autoFill)")
    public void autoFill(JoinPoint joinPoint, AutoFill autoFill) throws Exception {
        log.info("开始进行公共字段自动填充...");
        //获取到当前被拦截的方法上的数据库操作类型
//        MethodSignature methodSignature = (MethodSignature) joinPoint.getSignature();
        //获得方法上的注解对象
//        AutoFill autoFill = methodSignature.getMethod().getAnnotation(AutoFill.class);
        //获得数据库操作类型
        OperationType operationType = autoFill.value();
        //获取到当前被拦截的方法的参数--实体对象
        Object[] args = joinPoint.getArgs();
        if (ObjectUtils.isEmpty(args)) {
            return;
        }
        Object entity = args[0];

        Class<?> aClass = entity.getClass();
//        if (INSERT == operationType){
//            final Field createTimeField=aClass.getDeclaredField("createTime");
//            createTimeField.setAccessible(true);
//            createTimeField.set(entity, LocalDateTime.now());
//
//            final Field updateTimeField=aClass.getDeclaredField("updateTime");
//            updateTimeField.setAccessible(true);
//            updateTimeField.set(entity, LocalDateTime.now());
//
//            final Field createUserField=aClass.getDeclaredField("createUser");
//            createUserField.setAccessible(true);
//            createUserField.set(entity, BaseContext.getCurrentId());
//
//            final Field updateUserField=aClass.getDeclaredField("updateUser");
//            updateUserField.setAccessible(true);
//            updateUserField.set(entity, BaseContext.getCurrentId());
//
//
//        }else{
//            final Field updateTimeField=aClass.getDeclaredField("updateTime");
//            updateTimeField.setAccessible(true);
//            updateTimeField.set(entity, LocalDateTime.now());
//
//            final Field updateUserField=aClass.getDeclaredField("updateUser");
//            updateUserField.setAccessible(true);
//            updateUserField.set(entity, BaseContext.getCurrentId());
//        }
        if (INSERT == operationType) {

            fillField(entity, aClass, "createTime");

            fillField(entity, aClass, "updateTime");

            fillField(entity, aClass, "createUser");

            fillField(entity, aClass, "updateUser");
        } else {
            fillField(entity, aClass, "updateTime");

            fillField(entity, aClass, "updateUser");
        }
    }

    private void fillField(Object entity, Class<?> aClass, String fieldName) throws NoSuchFieldException, IllegalAccessException {
        final Field field = aClass.getDeclaredField(fieldName);
        field.setAccessible(true);
        if (field.getType() == LocalDateTime.class) {
            field.set(entity, LocalDateTime.now());
        } else {
            field.set(entity, BaseContext.getCurrentId());
        }
    }

}
